/**
 * Constraint
 * ----------------------------------------
 * 
 * - This class is used only for Struts 2.
 * - Creates session of constraints.
 * 
 * - methods:
 * 		- edit
 * 		- delete
 * 		- list
 * 
 * @author Caio Thomas
 * @version 28-10-2013
 */
package control;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;

import org.apache.struts2.interceptor.SessionAware;

import model.constraints.AbstractConstraint;
import model.constraints.XDF;
import model.constraints.XDFC;
import model.validator.ObserverSaxParser;
import model.validator.ValidateSaxParse;
import model.validator.XDFCValidate;
import model.validator.XDFValidate;

import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionSupport;

public class Constraint extends ActionSupport implements SessionAware {

	private static final long serialVersionUID = 1L;

	//constraint
	private String nameConstraint;
	private String contex;
	private String leftPath;
	private String leftValue;
	private String rightPath;
	private String rightValue;
	private String condition;
	
	private Map<String, Object> session;
	private ArrayList<AbstractConstraint> constraints = new ArrayList<AbstractConstraint>();
	private HashMap<String, ValidateSaxParse> validate = null; //string has namefile temp in server
	
	//aux
	private String action;
	private String id;		
	private String error;
	
	/* Get and Set's Methods */
	
	public HashMap<String, ValidateSaxParse> getValidate() {
		return validate;
	}

	public void setValidate(HashMap<String, ValidateSaxParse> validate) {
		this.validate = validate;
	}
	
	public String getNameConstraint() {
		return nameConstraint;
	}

	public void setNameConstraint(String nameConstraint) {
		this.nameConstraint = nameConstraint;
	}

	public String getContex() {
		return contex;
	}

	public void setContex(String contex) {
		this.contex = contex;
	}

	public String getLeftPath() {
		return leftPath;
	}

	public void setLeftPath(String leftPath) {
		this.leftPath = leftPath;
	}

	public String getLeftValue() {
		return leftValue;
	}

	public void setLeftValue(String leftValue) {
		this.leftValue = leftValue;
	}

	public String getRightPath() {
		return rightPath;
	}

	public void setRightPath(String rightPath) {
		this.rightPath = rightPath;
	}

	public String getRightValue() {
		return rightValue;
	}

	public void setRightValue(String rightValue) {
		this.rightValue = rightValue;
	}


	public Map<String, Object> getSession() {
		return session;
	}	
	
	@Override
	public void setSession(Map<String, Object> arg0) {
		session = arg0;
		
	}	
	
	public void setAction(String action) {
		this.action = action;
	}

	public String getAction() {
		return action;
	}
	
	public boolean isInsert() {
		return action.equals("insert") ? true : false; 
	}

	public void setId(String id) {
		this.id = id;
	}

	public String getId() {
		return id;
	} 
	
	public void setConstraints(ArrayList<AbstractConstraint> constraints) {
		this.constraints = constraints;
	}	
	
	public ArrayList<AbstractConstraint> getConstraints(){
		return constraints;
	}
	
	public void setCondition(String condition) {
		this.condition = condition;
	}

	public String getCondition() {
		return condition;
	}
	
	public void setError(String error) {
		this.error = error;
	}

	public String getError() {
		return error;
	}
		
	/* Methods */
	
	public String execute() {		
		singleSession();
        
		if(condition.equals("")) { //creates xdf
			System.out.println("INSERINDO XDF");
			XDF xdf = new XDF();
			xdf.setNameConstraint(nameConstraint);
			xdf.setContextFsa(contex);
			xdf.setSourceFsa(leftPath);
			xdf.setEquality(leftValue,"l");
			xdf.setTargetFsa(rightPath);
			xdf.setRightValue(rightValue);				
			
			if(xdf.getRightValue() == 0)//if is value			
				xdf.setEquality("v","r");
			else
				xdf.setEquality("n","r");
	
			XDFValidate val = new XDFValidate(xdf);
			if(isInsert() == true)
				validate.get(getKey()).add(val);	
			else
				validate.get(getKey()).getConstraints().get(Integer.parseInt(id)).setConstraint(xdf);					
		
		} else { // insert new XDFC
			
			System.out.println("INSERINDO XDFC");
			XDFC xdfc = new XDFC();
			xdfc.setNameConstraint(nameConstraint);
			xdfc.setContextFsa(contex);
			xdfc.setSourceFsa(leftPath);
			xdfc.setEquality(leftValue,"l");
			xdfc.setTargetFsa(rightPath);       			
			xdfc.setRightValue(rightValue);	

			try {
				xdfc.setConditional(condition);
			} catch (Exception e) {
				System.out.println("Error: insert condition!");				
			}
			
			if(xdfc.getRightValue() == 0)//if is value			
				xdfc.setEquality("v","r");
			else
				xdfc.setEquality("n","r");
			
			XDFCValidate val = new XDFCValidate(xdfc);
			if(isInsert() == true)
				validate.get(getKey()).add(val);	
			else
				validate.get(getKey()).getConstraints().get(Integer.parseInt(id)).setConstraint(xdfc);				
		}								
		
		session.put("validate", validate);		
		return "SUCCESS";		
	}
	
	public String list() {		
		singleSession();
		
		if(validate.get(getKey()).getConstraints().size() == 0)
			return "CONSTRAINT";
		
		for(ObserverSaxParser con: validate.get(getKey()).getConstraints())
			constraints.add((AbstractConstraint) con.getConstraint());	
										
		return "SUCCESS";
	}
		
	
	public String edit() {
		
		singleSession();
				
		if( Integer.parseInt(getId()) <= validate.get(getKey()).getConstraints().size()){
			AbstractConstraint ab = (AbstractConstraint) validate.get(getKey()).getConstraints().get(Integer.parseInt(getId())).getConstraint();
			
			nameConstraint = ab.getNameConstraint();
			contex = ab.getContext();
			leftPath = ab.getLeftPath();
			leftValue = ab.getLeftValue();
			rightPath = ab.getRightPath();
			rightValue = String.valueOf(ab.getRightValue());
			
			if(ab instanceof XDFC)
				condition = ((XDFC) ab).getCondExpr();
			
			return "SUCCESS";
		}
		
		error = "1";
		return "ERROR";
	}

	public String delete() {
		singleSession();

		System.out.println("value ID " + id);
		validate.get(getKey()).getConstraints().remove(Integer.parseInt(id));
		
		session.put("validate", validate);		
		return "SUCCESS";		
	}
	
	@SuppressWarnings("unchecked")
	public String results() {
		session = ActionContext.getContext().getSession();		
		validate = (HashMap<String, ValidateSaxParse>) session.get("validate");
		
		if(validate == null) //return page form
			return "CONSTRAINT";		
				
		return "SUCCESS";			
	} 	
	
	@SuppressWarnings("unchecked")
	public void singleSession() {
		session = ActionContext.getContext().getSession();		
		validate = (HashMap<String, ValidateSaxParse>) session.get("validate");
		
		if(validate == null){ //creates new session
			validate = new HashMap<String, ValidateSaxParse>();
			validate.put("filename", new ValidateSaxParse());
			session.put("validate", validate);
			System.out.println("novo validate sesssion");
		}			
	}
	
	public String getKey(){
		String key = new String("filename");
		for (String k : validate.keySet())
			key = k;
		
		return key;
	}
}
